<template>
  <div>
    <PostHeader></PostHeader>
    <ImgCutter ref="imgCutter" @cutDown="cutDown">
      <template #open></template>
    </ImgCutter>
    <el-row style="padding: 20px;">
      <el-col :span="4">
        <div style="display: flex; flex-direction: column;">
          <el-button @dragstart="dragstart($event, v)" draggable="true" @click="handleAddToMiddle(v)" :="v.btnConfig"
            :style="{ width: v.css.width + 'px', height: v.css.height + 'px' }" v-for="(v, i) in compList" :key="i"
            style="margin: 4px;">{{
              v.text }}</el-button>
        </div>
      </el-col>
      <el-col :span="12">
        <div class="phone" @drop="drop">
          <Vue3DraggableResizable @activated="activated(i)" :initW="v.css.width" :initH="v.css.height"
            v-model:x="v.css.x" v-model:y="v.css.y" v-model:w="v.css.width" v-model:h="v.css.height"
            v-for="(v, i) in compListMiddle" :parent="true" :draggable="true" :resizable="true" :key="i">
            <component :is="v.component" :style="v.css" :text="v.text"></component>
          </Vue3DraggableResizable>
        </div>
      </el-col>
      <el-col :span="8">
        <el-form label-width="auto">
          <div v-show="activeIndex !== -1">
            <el-form-item label="内容">
              <el-input v-model="rightText"></el-input>
            </el-form-item>
            <el-form-item :label="cssKeyToChinese(key)" v-for="(value, key) in rightData" :key="key">
              <el-input v-if="typeof value === 'number' || typeof value === 'string'" :type="cssToType(key)"
                v-model="rightData[key]" />
              <div v-if="typeof value === 'object' && value.type === 'button'">
                <el-button @click="changeTypeButton(key, v.value)"
                  :type="value.value === v.value ? 'primary' : 'default'" v-for="(v, i) in value.options" :key="i">{{
                    v.value }}</el-button>
              </div>
              <div v-if="typeof value === 'boolean'">
                <el-switch v-model="rightData[key]"></el-switch>
              </div>
            </el-form-item>
            <el-form-item label="操作">
              <el-button type="danger" @click="handleDelete">删除</el-button>
            </el-form-item>
          </div>
          <!-- <el-form-item label="宽度">
            <el-input type="text" v-model="rightData.width" />
          </el-form-item>
          <el-form-item label="高度">
            <el-input type="text" v-model="rightData.height" />
          </el-form-item>
          <el-form-item label="背景颜色">
            <el-input type="color" v-model="rightData.backgroundColor" />
          </el-form-item> -->
        </el-form>
      </el-col>
    </el-row>
  </div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import type { CompListState } from '@/types'
import { compList } from './compList'
import { cloneDeep } from 'lodash'
import { cssKeyToChinese } from '@/constants'
import ImgCutter from 'vue-img-cutter'
import { uploadImage } from '@/api';
// 插件插件实例
const imgCutter = ref()
// 中间数据
const compListMiddle = ref<CompListState[]>([]);
// 中间选中数据索引
const activeIndex = ref(-1)
// 将左侧添加到中间
const addToMiddle = (v: CompListState, pos?: { x?: number, y?: number, url?: string }) => {
  const data = cloneDeep(v)
  // 是否修改默认设置
  if (pos) {
    Object.keys(pos).map(key => {
      if (pos[key]) {
        data.css[key] = pos[key]
      }
    })
  }
  compListMiddle.value.push({
    ...data,
    id: new Date().getTime(),
  })
}

// 右侧数据
const rightData = ref<{ [propsName: string]: any }>({});
// 临时拖拽位置数据
const dragData = ref({
  left: {
    offsetX: 0,
    offsetY: 0,
  },
  middle: {
    offsetX: 0,
    offsetY: 0,
  }
})
// 临时拖拽元素数据
const dragItem = ref({} as CompListState)
// 右侧文本数据
const rightText = ref('')
/************************* 拖放 *********************************/
document.addEventListener('dragover', e => e.preventDefault())

const dragstart = ($, v) => {
  dragItem.value = v
  dragData.value.left.offsetX = $.offsetX
  dragData.value.left.offsetY = $.offsetY
}

const drop = ($) => {
  dragData.value.middle.offsetX = $.offsetX
  dragData.value.middle.offsetY = $.offsetY
  // 计算位置
  const x = dragData.value.middle.offsetX - dragData.value.left.offsetX
  const y = dragData.value.middle.offsetY - dragData.value.left.offsetY
  // 是否上传的是图片
  if (dragItem.value.beforeCreate) {
    // 选择一个图片
    dragItem.value.beforeCreate(dragItem.value.isCurt).then(({ name, url }) => {
      // 图片是否需要裁剪
      if (dragItem.value.isCurt) {
        // 触发插件的handleOpen
        imgCutter.value.handleOpen({
          src: url,
          name
        })
      } else {
        // 不需要裁剪
        addToMiddle(dragItem.value, { x, y, url })
      }
    })
    // 非图片
  } else {
    addToMiddle(dragItem.value, { x, y })
  }
}

/************************* 事件 *********************************/
// 中间选中事件
const activated = (i) => {
  activeIndex.value = i;
  rightData.value = compListMiddle.value[i].css
  rightText.value = compListMiddle.value[i].text
}

// 右侧 type = button 切换事件
const changeTypeButton = (key, value) => {
  console.log(1231)
  const data = cloneDeep(compListMiddle.value);
  data[activeIndex.value].css[key].value = value
  compListMiddle.value = data;
  rightData.value = compListMiddle.value[activeIndex.value].css
}
// 中间删除事件
const handleDelete = () => {
  compListMiddle.value.splice(activeIndex.value, 1);
  activeIndex.value = -1
}

// 左侧点击事件
const handleAddToMiddle = (v) => {
  // 图片
  if (v.beforeCreate) {
    v.beforeCreate().then(({ url, name }) => {
      if (v.isCurt) {
        // 裁剪
        imgCutter.value.handleOpen({
          src: url,
          name
        })
      } else {
        addToMiddle(v, { url })
      }

    })
  } else {
    addToMiddle(v)
  }
  dragData.value = {
    left: {
      offsetX: 0,
      offsetY: 0,
    },
    middle: {
      offsetX: 0,
      offsetY: 0,
    }
  }
}
// 裁剪完成
const cutDown = async (file) => {
  const x = dragData.value.middle.offsetX - dragData.value.left.offsetX
  const y = dragData.value.middle.offsetY - dragData.value.left.offsetY
  const resp = await uploadImage(file.file)
  addToMiddle(dragItem.value, { x, y, url: resp.data.data.url })
}
/************************* 工具 *********************************/
const cssToType = (css: string | number) => {
  if (typeof css === 'number') return 'number'
  if (css.toLocaleLowerCase().includes('color')) return 'color'
  return 'text'
}

/************************* 侦听器 *********************************/
watch(rightText, newValue => {
  console.log('--------')
  console.log(compListMiddle.value[activeIndex.value].text)
  compListMiddle.value[activeIndex.value].text = newValue
})

</script>
<style lang="scss" scoped>
.phone {
  width: 375px;
  height: 567px;
  // background-color: red;
  border: 1px solid #ccc;
  position: relative;
  overflow: hidden;
  margin: auto;
}
</style>